package com.six.service;

import com.six.domain.dto.*;
import com.six.domain.entity.Dish;
import com.six.domain.entity.Order;
import com.six.domain.entity.OrderItem;
import com.six.domain.vo.MyOrderVO;
import com.six.enums.TableStatus;
import com.six.mapper.DishMapper;
import com.six.mapper.OrderMapper;
import com.six.common.BizException;
import com.six.mapper.TableMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class OrderService {

    private final OrderMapper orderMapper;
    private final DishMapper dishMapper;
    private final TableMapper tableMapper;

    // ================= 1. 创建订单 =================
    @Transactional
    public Long createOrder(OrderCreateDTO dto) {
        try {
            List<Long> dishIds = dto.getItems().stream()
                    .map(OrderItemParam::getDishId).collect(Collectors.toList());
            List<Dish> dishes = dishMapper.selectById(dishIds);
            Map<Long, Dish> dishMap = dishes.stream()
                    .collect(Collectors.toMap(Dish::getId, d -> d));

            BigDecimal total = dto.getItems().stream()
                    .map(p -> dishMap.get(p.getDishId()).getPrice()
                            .multiply(BigDecimal.valueOf(p.getQuantity())))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            Order order = new Order();
            order.setUserId(dto.getUserId());
            order.setStoreId(dto.getStoreId());
            order.setTableId(dto.getTableId());
            order.setTotalPrice(total);
            order.setStatus(dto.getStatus());
            orderMapper.insertOrder(order);

            List<OrderItem> items = dto.getItems().stream()
                    .map(p -> {
                        Dish d = dishMap.get(p.getDishId());
                        OrderItem i = new OrderItem();
                        i.setOrderId(order.getId());
                        i.setDishId(p.getDishId());
                        i.setSpecId(p.getSpecId());
                        i.setQuantity(p.getQuantity());
                        i.setPrice(d.getPrice());
                        i.setDishName(d.getName());
                        return i;
                    }).collect(Collectors.toList());
            orderMapper.insertItems(items);
            if (dto.getTableId() != null) {
                System.out.println("👉【下单占用桌台】tableId = " + dto.getTableId());

                int rows = tableMapper.updateStatus(dto.getTableId(), "OCCUPIED");
                System.out.println("👉【桌台状态更新】影响行数 = " + rows);
            }
            return order.getId();

        } catch (Exception e) {
            e.printStackTrace(); // 强制打印
            throw new RuntimeException(e); // 让 Spring 也打印
        }
    }
    // ================= 2. 商家修改订单 =================
    @Transactional
    public void updateOrder(Long orderId, OrderUpdateDTO dto) {
        Order order = orderMapper.selectById(orderId);
        if (order == null) throw new BizException("订单不存在");
        if (!order.getStoreId().equals(dto.getStoreId()))
            throw new BizException("无权操作其他门店订单");

        List<Long> dishIds = dto.getItems().stream()
                .map(OrderItemUpdateParam::getDishId)
                .collect(Collectors.toList());
        List<Dish> dishes = dishMapper.selectById(dishIds);
        if (dishes.size() != dishIds.size())
            throw new BizException("存在无效菜品");

        Map<Long, Dish> dishMap = dishes.stream()
                .collect(Collectors.toMap(Dish::getId, d -> d));

        List<OrderItem> newItems = dto.getItems().stream()
                .map(p -> {
                    Dish d = dishMap.get(p.getDishId());
                    OrderItem i = new OrderItem();
                    i.setOrderId(orderId);
                    i.setDishId(p.getDishId());
                    i.setSpecId(p.getSpecId());
                    i.setPrice(d.getPrice());
                    i.setQuantity(p.getQuantity());
                    i.setDishName(d.getName());
                    return i;
                }).collect(Collectors.toList());

        BigDecimal newTotal = newItems.stream()
                .map(i -> i.getPrice().multiply(BigDecimal.valueOf(i.getQuantity())))
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        order.setStatus(dto.getStatus());
        order.setTotalPrice(newTotal);
        orderMapper.updateById(order);

        orderMapper.deleteItemsByOrderId(orderId);
        orderMapper.insertItems(newItems);
    }
    public List<MyOrderVO> myOrders(OrderQueryDTO dto) {
        return orderMapper.selectMyOrders(dto);
    }

    @Transactional
    public void pay(Long orderId, String channel) {
        Order order = orderMapper.selectById(orderId);
        if (order == null || order.getStatus() != 1)
            throw new BizException("订单不可支付");
        order.setStatus(2);
        order.setPayChannel(channel);
        orderMapper.updateById(order);
    }

    @Transactional
    public void cancel(Long orderId) {
        Order order = orderMapper.selectById(orderId);
        if (order == null || order.getStatus() != 1) {
            throw new BizException("订单不可取消");
        }

        // 更新订单状态
        order.setStatus(3); // 已取消
        orderMapper.updateById(order);

        // 释放桌台
        if (order.getTableId() != null) {
            System.out.println("👉【取消订单释放桌台】tableId = " + order.getTableId());
            int rows = tableMapper.updateStatus(order.getTableId(), "FREE");
            System.out.println("👉【取消释放桌台更新行数】= " + rows);
        }
    }
    public MyOrderVO detail(Long id) {
        return orderMapper.selectDetail(id);
    }
    @Transactional
    public void completeOrder(Long orderId) {
        Order order = orderMapper.selectById(orderId);
        System.out.println("👉【原始订单】id=" + order.getId() + ", tableId=" + order.getTableId());
        if (order == null || order.getStatus() != 2) {
            throw new BizException("订单状态异常，无法完成");
        }
        order.setStatus(4); // 已完成
        orderMapper.updateById(order);

        // 释放桌台
        if (order.getTableId() != null) {
            tableMapper.updateStatus(order.getTableId(), TableStatus.FREE.name());
        }
        System.out.println("👉【完成订单释放桌台】tableId = " + order.getTableId());
        int rows = tableMapper.updateStatus(order.getTableId(), "FREE");
        System.out.println("👉【释放桌台更新行数】= " + rows);
        System.out.println("👉【事务即将提交】");
    }
}